home *** CD-ROM | disk | FTP | other *** search
- unit MRUFList;
-
- (* Implements a Recently-Used Files List *)
-
- (* Constructed by Robert R. Marsh, S.J., 1995 *)
- (* Use freely, distribute widely, charge nothing*)
- (* If you like it you could always give some *)
- (* money to your favorite charity. *)
-
- (* Comments, bug-reports, praise and blame to: *)
- (* RobMarsh@AOL.COM *)
-
- interface
-
- uses
- SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
- Forms, Dialogs, Menus, IniFiles;
-
- type
- TRecentFileEvent = procedure(Sender: TObject; LatestFile: string) of object;
-
- type
- TRecentFiles = class(TComponent)
- private
- FMenu : TMenuItem;
- Divider : TMenuItem;
- FMaxFiles : integer;
- FIniFileName: string;
- FLatestFile : string;
- FOnClick : TRecentFileEvent;
- procedure SetLatestFile(value: string);
- procedure SetMenu(value: TMenuItem);
- procedure SetMaxFiles(value: integer);
- procedure MenuOnClick(Sender: TObject);
- function DividerPlace: integer;
- protected
- procedure Click(RecentFile: string);
- public
- constructor Create(AOwner: TComponent); override;
- procedure SaveToIniFile;
- procedure LoadFromIniFile;
- property LatestFile: string read FLatestFile write SetLatestFile;
- published
- property Menu : TMenuItem read FMenu write SetMenu;
- property MaxFiles : integer read FMaxFiles write SetMaxFiles;
- property IniFileName: string read FIniFileName write FIniFileName;
- property OnClick : TRecentFileEvent read FOnClick write FOnClick;
- end;
-
- procedure Register;
-
- implementation
-
- procedure Register;
- begin
- RegisterComponents('Mine', [TRecentFiles]);
- end;
-
- {we frequently need to know both if the Divider}
- {has been added and, if so, where it is}
- function TRecentFiles.DividerPlace: integer;
- begin
- Result:=-1;
- if FMenu <> nil then
- begin
- Result:=Menu.IndexOf(Divider);
- end;
- end;
-
- procedure TRecentFiles.SetMenu(value: TMenuItem);
- begin
- FMenu:=value;
- end;
-
- procedure TRecentFiles.SetMaxFiles(value: integer);
- var
- n: integer;
- begin
- {the Max value of MaxFiles is 9}
- if value <=9 then
- begin
- FMaxFiles:=value;
- end
- else
- begin
- FMaxFiles:=9;
- end;
- if (FMenu <> nil) and (DividerPlace <> -1) then
- begin
- {trim off any entries more MaxFiles}
- while Menu.Count > DividerPlace + FMaxFiles + 1 do
- begin
- Menu.Delete(Menu.Count-1);
- end;
- {if neccesary delete the divider too}
- if FMaxFiles = 0 then
- begin
- Menu.Delete(Menu.Count-1);
- end;
- end;
- end;
-
- procedure TRecentFiles.SetLatestFile(value: string);
- var
- NewMenuItem: TMenuItem;
- n : integer;
- Thiscaption: string;
- OldPlace : integer;
- DividerPos : integer;
- begin
- FLatestFile:=value;
- if (Menu <> nil) and (MaxFiles > 0) and
- (FLatestFile <> '') then
- begin
- {special case - the divider}
- if DividerPlace < 0 then
- begin
- Menu.Add(Divider);
- end;
- {is the new Name already there?}
- DividerPos:=DividerPlace;
- n:=DividerPos+1;
- while (n < Menu.Count) do
- begin
- if FLatestFile = Copy(Menu.Items[n].Caption,4,high(string)) then
- begin
- OldPlace:=n;
- Break;
- end
- else
- begin
- inc(n);
- end;
- end;
- if n >= Menu.Count then {we add}
- begin
- NewMenuItem:=TMenuItem.Create(Self);
- NewMenuItem.Caption:='&1 '+FLatestFile;
- {what happens if we click it}
- NewMenuItem.OnClick:=MenuOnClick;
- Menu.Insert(DividerPos+1,NewMenuItem);
- end
- else {we insert}
- begin
- NewMenuItem:=Menu.Items[OldPlace];
- Menu.Delete(OldPlace);
- Menu.Insert(DividerPos+1,NewMenuItem);
- end;
- {now change the 'hot' keys}
- for n:=DividerPos+1 to Menu.Count - 1 do
- begin
- ThisCaption:=Menu.Items[n].Caption;
- ThisCaption[2]:=Chr(n - DividerPos + Ord('1') -1);
- Menu.Items[n].Caption:=ThisCaption;
- end;
- {delete any excess items}
- if Menu.Count > DividerPos + MaxFiles + 1 then
- begin
- Menu.Delete(Menu.Count-1);
- end;
- end;
- end;
-
- procedure TRecentFiles.Click(RecentFile: string);
- begin
- if Assigned(FOnClick) then FOnClick(Self,RecentFile);
- end;
-
- procedure TRecentFiles.SaveToIniFile;
- var
- IniFile : TIniFile;
- n : integer;
- DividerPos: integer;
- begin
- if Menu <> nil then
- begin
- {if this property is blank we use the default}
- if IniFileName = '' then
- begin
- IniFileName:=ChangeFileExt(ExtractFileName(Application.ExeName),'.INI')
- end;
- IniFile:=TIniFile.Create(IniFileName);
- IniFile.EraseSection('FileHistory');
- IniFile.WriteInteger('FileHistory','MaxFiles',MaxFiles);
- if (Menu <> nil) and (DividerPlace <> -1) then
- begin
- DividerPos:=DividerPlace;
- n:=DividerPos+1;
- while n < Menu.Count do
- begin
- IniFile.WriteString('FileHistory','File'+Chr(n+Ord('1')-1-DividerPos),Copy(Menu.Items[n].Caption,4,high(string)));
- inc(n);
- end;
- IniFile.Free;
- end;
- end;
- end;
-
- procedure TRecentFiles.LoadFromIniFile;
- var
- IniFile: TIniFile;
- n : integer;
- Name : string;
- begin
- if Menu <> nil then
- begin
- if IniFileName = '' then
- begin
- IniFileName:=ChangeFileExt(ExtractFileName(Application.ExeName),'.INI')
- end;
- IniFile:=TIniFile.Create(IniFileName);
- MaxFiles:=0;
- MaxFiles:=IniFile.ReadInteger('FileHistory','MaxFiles',MaxFiles);
- n:=1;
- while true do
- begin
- Name:=IniFile.ReadString('FileHistory','File'+Chr(n+Ord('1')-1),'');
- if Name = '' then
- begin
- Break;
- end;
- LatestFile:=Name;
- inc(n);
- end;
- end;
- end;
-
- constructor TRecentFiles.Create(AOwner: TComponent);
- begin
- inherited Create(AOwner);
- FMaxFiles:=0;
- FMenu:=nil;
- Divider:=TMenuItem.Create(Self);
- Divider.Caption:='-';
- end;
-
- procedure TRecentFiles.MenuOnClick(Sender: TObject);
- var
- Name: string;
- begin
- begin
- Name:=Copy(TMenuItem(Sender).Caption,4,high(string));
- Click(Name);
- end;
- end;
-
- end.